package com.example.learn_gl_android.model

import android.content.Context
import android.opengl.GLES30

import android.opengl.Matrix
import com.example.learn_gl_android.anglib.core.IObject
import com.example.learn_gl_android.anglib.core.Object
import com.example.learn_gl_android.anglib.util.MyGLUtil
import com.example.learn_gl_android.anglib.core.gl.DefaultGLIRenderer
import com.example.learn_gl_android.anglib.core.gl.DefaultGLSurfaceView
import com.example.learn_gl_android.anglib.core.gl.ServiceLocator
import com.example.learn_gl_android.anglib.core.carmera.Camera
import com.example.learn_gl_android.anglib.core.gl.shader.SimpleShader
import com.example.learn_gl_android.anglib.core.renderer.IRenderer
import com.example.learn_gl_android.anglib.core.renderer.Renderer
import com.example.learn_gl_android.anglib.core.renderer.matrial.Color
import com.example.learn_gl_android.anglib.core.renderer.matrial.IndexTexture
import com.example.learn_gl_android.anglib.core.renderer.matrial.Material
import com.example.learn_gl_android.anglib.core.transform.DefaultTransform

class TriangleGLSurfaceView2(context: Context) : DefaultGLSurfaceView(context) {
    private var mRenderer  = DefaultGLIRenderer()
    private var camera = Camera()
    private lateinit var mShader : SimpleShader
    private lateinit var mTriangle : Triangle
    private var transform = DefaultTransform()
    private val mat : Material
    private  var objRender : IRenderer
    private lateinit var obj : IObject

    init {
        ServiceLocator.provide(this)

        setEGLContextClientVersion(3)
        setRenderer(mRenderer)
        renderMode = RENDERMODE_CONTINUOUSLY

        mRenderer.addToOnInitHook {
            onSurfaceCreated()
        }

        mRenderer.addToOnDrawFrameHook {
            onDrawFrame()
        }

        mRenderer.addToOnScreenSizeChangedHook{
            w,h -> onSurfaceChanged(w, h)
        }



        val c0 = Color(1f,0f,0f,0f)
        val c1 = Color(0f,0f,1f,0f)
        val c2 = Color(0f,1f,0f,0f)

        val tex = IndexTexture(arrayOf(c0, c1, c2))
         mat = Material(tex)
        objRender = Renderer(mat)
    }



     private fun onSurfaceCreated() {
        GLES30.glClearColor(1f, .3f, .3f , 0f)

        val mUnitSize = .2f

        val vertices :FloatArray = arrayOf(
            -4*mUnitSize, 0f, 0f,
            0f, -4*mUnitSize,0f,
            0f, 0f, -4*mUnitSize
        ).toFloatArray()

         mTriangle = Triangle(vertices)


         mShader  = SimpleShader()
         transform.scale(3f, 3f, 3f)
         transform.translate(0f,0f,1f) // z 轴正方向从屏幕内部向外, 右手坐标系

         obj = Object()
         obj.addComponent(mTriangle)
         obj.addComponent(transform)
         obj.addComponent(objRender)


        GLES30.glEnable(GLES30.GL_DEPTH_TEST)
    }

    private fun onSurfaceChanged(width: Int, height: Int) {
        GLES30.glViewport(0,0,width, height)
        val ratio = (width.toFloat()/height)

        Matrix.frustumM(camera.projectionMatrix.elements, 0, -ratio, ratio, -1f, 1f, 1f,10f)
        Matrix.setLookAtM(camera.viewMatrix.elements, 0, 0f, 0f,3f,
            0f,0f,0f,
            0f, 1f, 0f)

    }

    private fun onDrawFrame() {
        GLES30.glClear(GLES30.GL_DEPTH_BUFFER_BIT or GLES30.GL_COLOR_BUFFER_BIT)

        transform.rotate(1f,0f,0f)

        mShader.matrixBuffer(camera.picture(transform.transformMatrix).elements)

        mShader.vertexCount(mTriangle.vertexCount())
        mShader.vertexBuffer(MyGLUtil.initFloatBuffer(mTriangle.vertices))

        mShader.colorBuffer(mat.texture.toFloatBuffer())

        mShader.draw()
    }
}